# taken from http://code.djangoproject.com/wiki/XML-RPC
# Patchless XMLRPC Service for Django
# Kind of hacky, and stolen from Crast on irc.freenode.net:#django
# Self documents as well, so if you call it from outside of an XML-RPC Client
# it tells you about itself and its methods
#
# Brendan W. McAdams <brendan.mcadams@thewintergrp.com>

# SimpleXMLRPCDispatcher lets us register xml-rpc calls w/o
# running a full XMLRPC Server.  It's up to us to dispatch data

from SimpleXMLRPCServer import SimpleXMLRPCDispatcher
from django.http import HttpResponse
from django.template import RequestContext
from django.template.loader import render_to_string
from django.forms import model_to_dict

# Create a Dispatcher; this handles the calls and translates info to function maps
#dispatcher = SimpleXMLRPCDispatcher() # Python 2.4
dispatcher = SimpleXMLRPCDispatcher(allow_none=False, encoding=None) # Python 2.5

 

def rpc_handler(request):
    """
    the actual handler:
    if you setup your urls.py properly, all calls to the xml-rpc service
    should be routed through here.
    If post data is defined, it assumes it's XML-RPC and tries to process as such
    Empty post assumes you're viewing from a browser and tells you about the service.
    """

    response = HttpResponse()
    if len(request.POST):
        response.write(dispatcher._marshaled_dispatch(request.raw_post_data))
    else:
        
        methods = dispatcher.system_listMethods()
        mlist = list()
        for method in methods:
            d = {"name":method}
            # right now, my version of SimpleXMLRPCDispatcher always
            # returns "signatures not supported"... :(
            # but, in an ideal world it will tell users what args are expected
           # d["signature"] = dispatcher.system_methodSignature(method)

            # this just reads your docblock, so fill it in!
            d["help"] =  dispatcher.system_methodHelp(method)
            mlist.append(d)
        response.write(render_to_string("notification/xmlrpc_help.html",
                                        {"methods":mlist}, 
                                        context_instance=RequestContext(request)))

    response['Content-length'] = str(len(response.content))
    return response


"""
methods to implement:

get last X news
           releases
get info about user X
get projex X
get release X of project X
get last release name of project X
get download url of release X of project X

"""
from projects.models import Project, Release

def get_project(p_slug):
    """
    arguments: String:project_slug <br/>
    get some information about a project
    """
    try:
        p = Project.objects.get(slug=p_slug)
        pd = model_to_dict(p)
        fields = ['is_inactive', 'hide', 'description', 'tags', #'markup',
                  'homepage_link', 'summary', 'name']
        return dict([(k, pd[k]) for k in fields])
    except Project.DoesNotExist:
        return None
    
dispatcher.register_function(get_project, 'get_project')


def _get_latest_release(project_slug):
    r = Release.objects.filter(project__slug=project_slug,
                                project__is_inactive=False)    
    if r.count():
        return r[0]

def get_latest_version(p_slug):
    """
    arguments: String:project_slug <br/>
    get the name of the latest version of a project
    """
    r = _get_latest_release(p_slug)
    if r:
        return r.version
    else:
        return ""
    
dispatcher.register_function(get_latest_version, 'get_latest_version')
    
def get_latest_release(p_slug):
    """
    arguments: String:project_slug <br/>
    get some information about the latest release of a project
    """
    r = _get_latest_release(p_slug)
    if not r:
        return ""
    fields = ["summary", "changelog", "created", "notes_url", "download_url"]
    return dict([(k, getattr(r, k)) for k in fields])

dispatcher.register_function(get_latest_release, "get_latest_release")

# you have to manually register all functions that are xml-rpc-able with the dispatcher
# the dispatcher then maps the args down.
# The first argument is the actual method, the second is what to call it from the XML-RPC side...
#dispatcher.register_function(multiply, 'multiply')
 
